#!/usr/bin/env node
/**
 * 开发环境助手 CLI
 * 提供命令行界面，可以直接在终端中使用
 * 完全离线版本 - 不依赖网络连接
 */

import * as commander from 'commander';
import * as chalk from 'chalk';
import * as figlet from 'figlet';
import * as path from 'path';
import * as fs from 'fs/promises';
import { executeCommand, getDevEnvironment, checkProjectEnvironment, createDevConfig, manageEnvVariables, backupProject } from './utils/system';
import logger from './utils/logger';
import { SystemMonitor } from './monitor';

// 创建命令行程序
const program = new commander.Command();

// 显示标题
console.log(
    chalk.blue(
        figlet.textSync('DevAssist', { horizontalLayout: 'full' })
    )
);

// 设置版本和描述
program
    .version('0.1.0')
    .description('开发环境助手 (离线版) - 提供本地环境监控、项目分析和开发工具');

// 系统监控命令
program
    .command('monitor')
    .description('监控系统资源使用情况')
    .option('-i, --interval <seconds>', '监控间隔（秒）', '60')
    .option('-t, --time <minutes>', '监控时长（分钟）', '0')
    .action(async (options) => {
        try {
            console.log(chalk.green('开始监控系统资源...'));

            const interval = parseInt(options.interval, 10);
            const duration = parseInt(options.time, 10) * 60 * 1000; // 转换为毫秒

            // 获取系统信息
            const systemInfo = await getDevEnvironment();
            console.log(chalk.yellow('系统信息:'));
            console.log(`操作系统: ${systemInfo.os}`);
            console.log(`Shell: ${systemInfo.shell}`);
            console.log(`可用工具: ${systemInfo.tools.join(', ')}`);
            console.log('');

            // 创建监控器
            const configPath = path.join(__dirname, '..', 'config', 'monitor.json');
            const monitor = new SystemMonitor(configPath);

            // 设置事件处理
            monitor.on('metrics', (metrics) => {
                console.clear();
                console.log(chalk.green('系统监控 - 按 Ctrl+C 退出'));
                console.log('');
                console.log(chalk.yellow('时间: ') + new Date(metrics.timestamp).toLocaleString());
                console.log('');

                // CPU 使用率
                const cpuBar = createProgressBar(metrics.cpu.usage);
                console.log(chalk.yellow('CPU 使用率: ') + cpuBar + ` ${metrics.cpu.usage.toFixed(1)}%`);

                // 内存使用率
                const memBar = createProgressBar(metrics.memory.usage);
                console.log(chalk.yellow('内存使用率: ') + memBar + ` ${metrics.memory.usage.toFixed(1)}% (${formatBytes(metrics.memory.used)} / ${formatBytes(metrics.memory.total)})`);

                // 磁盘使用率
                const diskBar = createProgressBar(metrics.disk.usage);
                console.log(chalk.yellow('磁盘使用率: ') + diskBar + ` ${metrics.disk.usage.toFixed(1)}% (${formatBytes(metrics.disk.used)} / ${formatBytes(metrics.disk.total)})`);

                // 系统负载
                console.log(chalk.yellow('系统负载: ') + metrics.cpu.loadAvg.map(load => load.toFixed(2)).join(', '));

                // 电池信息（如果可用）
                if (metrics.battery) {
                    const batteryBar = createProgressBar(metrics.battery.level);
                    const chargingStatus = metrics.battery.charging ? chalk.green('充电中') : chalk.yellow('放电中');
                    console.log(chalk.yellow('电池状态: ') + batteryBar + ` ${metrics.battery.level.toFixed(1)}% (${chargingStatus})`);
                }
            });

            monitor.on('threshold_exceeded', (data) => {
                console.log(chalk.red(`警告: ${data.metric} 使用率 (${data.value.toFixed(1)}%) 超过阈值 ${data.threshold}%`));
            });

            // 启动监控
            await monitor.start();

            // 如果设置了监控时长，则在指定时间后停止
            if (duration > 0) {
                setTimeout(async () => {
                    await monitor.stop();
                    console.log(chalk.green('监控已完成'));
                    process.exit(0);
                }, duration);
            }

            // 处理退出信号
            process.on('SIGINT', async () => {
                await monitor.stop();
                console.log(chalk.green('监控已停止'));
                process.exit(0);
            });
        } catch (error) {
            console.error(chalk.red('监控失败:'), error.message);
            process.exit(1);
        }
    });

// 分析项目命令
program
    .command('analyze [path]')
    .description('分析项目结构和依赖')
    .action(async (projectPath = '.') => {
        try {
            console.log(chalk.green(`分析项目: ${projectPath}`));

            // 检查项目环境
            const projectInfo = await checkProjectEnvironment(projectPath);

            console.log(chalk.yellow('项目信息:'));
            console.log(`类型: ${chalk.cyan(projectInfo.type)}`);
            console.log(`依赖数量: ${chalk.cyan(projectInfo.dependencies.length)}`);

            if (projectInfo.dependencies.length > 0) {
                console.log('');
                console.log(chalk.yellow('主要依赖:'));
                projectInfo.dependencies.slice(0, 10).forEach(dep => {
                    console.log(`- ${dep}`);
                });

                if (projectInfo.dependencies.length > 10) {
                    console.log(chalk.gray(`...以及其他 ${projectInfo.dependencies.length - 10} 个依赖`));
                }
            }

            if (projectInfo.configs.length > 0) {
                console.log('');
                console.log(chalk.yellow('配置文件:'));
                projectInfo.configs.forEach(config => {
                    console.log(`- ${config}`);
                });
            }

            // 获取项目结构
            console.log('');
            console.log(chalk.yellow('项目结构:'));

            const { stdout: fileTree } = await executeCommand(`find "${projectPath}" -type f -not -path "*/node_modules/*" -not -path "*/\\.git/*" -not -path "*/__pycache__/*" | sort | head -n 20`);

            console.log(fileTree);
            console.log(chalk.gray('(只显示前 20 个文件)'));

            // 获取系统资源使用情况
            console.log('');
            console.log(chalk.yellow('系统资源:'));
            const { stdout: diskSpace } = await executeCommand('df -h .');
            console.log(diskSpace);

        } catch (error) {
            console.error(chalk.red('分析项目失败:'), error.message);
            process.exit(1);
        }
    });

// 项目备份命令
program
    .command('backup [path]')
    .description('创建项目备份')
    .option('-e, --exclude <patterns>', '排除的文件模式，用逗号分隔', '')
    .action(async (projectPath = '.', options) => {
        try {
            console.log(chalk.green(`备份项目: ${projectPath}`));

            const excludePatterns = options.exclude ? options.exclude.split(',') : [];

            if (excludePatterns.length > 0) {
                console.log(chalk.yellow(`排除的文件模式: ${excludePatterns.join(', ')}`));
            }

            const result = await backupProject(projectPath, { exclude: excludePatterns });

            if (result.success) {
                console.log(chalk.green(`备份成功: ${result.backupPath}`));
                console.log(chalk.yellow(`备份名称: ${result.backupName}`));
            } else {
                console.error(chalk.red(`备份失败: ${result.error}`));
                process.exit(1);
            }
        } catch (error) {
            console.error(chalk.red('备份项目失败:'), error.message);
            process.exit(1);
        }
    });

// 环境变量管理命令
program
    .command('env [path]')
    .description('管理项目环境变量')
    .option('-g, --get', '获取所有环境变量')
    .option('-s, --set <keyValue>', '设置环境变量，格式为 KEY=VALUE')
    .option('-d, --delete <key>', '删除环境变量')
    .action(async (projectPath = '.', options) => {
        try {
            if (options.get) {
                const vars = await manageEnvVariables(projectPath, 'get');
                console.log(chalk.yellow('环境变量:'));

                if (Object.keys(vars).length === 0) {
                    console.log(chalk.gray('没有环境变量'));
                } else {
                    for (const [key, value] of Object.entries(vars)) {
                        console.log(`${key}=${value}`);
                    }
                }
            } else if (options.set) {
                const [key, value] = options.set.split('=');
                if (!key || !value) {
                    console.error(chalk.red('无效的格式，应为 KEY=VALUE'));
                    process.exit(1);
                }

                const result = await manageEnvVariables(projectPath, 'set', { [key]: value });

                if (result.success) {
                    console.log(chalk.green(`已设置环境变量: ${key}=${value}`));
                } else {
                    console.error(chalk.red(`设置环境变量失败: ${result.error}`));
                    process.exit(1);
                }
            } else if (options.delete) {
                const key = options.delete;
                const result = await manageEnvVariables(projectPath, 'delete', { [key]: '' });

                if (result.success) {
                    console.log(chalk.green(`已删除环境变量: ${key}`));
                } else {
                    console.error(chalk.red(`删除环境变量失败: ${result.error}`));
                    process.exit(1);
                }
            } else {
                console.log(chalk.yellow('请指定操作: --get, --set 或 --delete'));
            }
        } catch (error) {
            console.error(chalk.red('管理环境变量失败:'), error.message);
            process.exit(1);
        }
    });

// 创建开发配置命令
program
    .command('init [path]')
    .description('初始化开发环境配置')
    .option('-t, --type <type>', '项目类型 (nodejs, python, java, etc.)')
    .action(async (projectPath = '.', options) => {
        try {
            console.log(chalk.green(`初始化开发环境配置: ${projectPath}`));

            // 检查项目环境
            const projectInfo = await checkProjectEnvironment(projectPath);
            const projectType = options.type || projectInfo.type;

            console.log(chalk.yellow(`检测到项目类型: ${projectType}`));

            // 创建开发配置
            const result = await createDevConfig(projectPath, {
                type: projectType,
                dependencies: projectInfo.dependencies,
                configs: projectInfo.configs
            });

            if (result.success) {
                console.log(chalk.green(`开发配置已创建: ${result.configPath}`));
            } else {
                console.error(chalk.red(`创建开发配置失败: ${result.error}`));
                process.exit(1);
            }
        } catch (error) {
            console.error(chalk.red('初始化开发环境配置失败:'), error.message);
            process.exit(1);
        }
    });

// 执行命令
program
    .command('exec <command>')
    .description('执行命令并记录输出')
    .option('-o, --output <file>', '输出文件', 'command-output.log')
    .action(async (command, options) => {
        try {
            console.log(chalk.green(`执行命令: ${command}`));

            const startTime = Date.now();
            const result = await executeCommand(command);
            const endTime = Date.now();
            const duration = (endTime - startTime) / 1000;

            console.log(chalk.yellow(`执行时间: ${duration.toFixed(2)}秒`));

            if (result.success) {
                console.log(chalk.green('命令执行成功'));
                console.log(result.stdout);

                if (result.stderr) {
                    console.log(chalk.yellow('错误输出:'));
                    console.log(result.stderr);
                }

                // 保存输出到文件
                const outputContent = `
命令: ${command}
执行时间: ${new Date().toISOString()}
持续时间: ${duration.toFixed(2)}秒
状态: 成功
------- 标准输出 -------
${result.stdout}
------- 错误输出 -------
${result.stderr || '无'}
`;

                await fs.writeFile(options.output, outputContent);
                console.log(chalk.green(`输出已保存到: ${options.output}`));
            } else {
                console.error(chalk.red('命令执行失败'));
                console.error(`错误: ${result.error}`);

                if (result.stdout) {
                    console.log(chalk.yellow('标准输出:'));
                    console.log(result.stdout);
                }